﻿//bibaoke.com

using System;
using Less.Text;

namespace Less.SqlParser
{
    /// <summary>
    /// string 扩展方法
    /// </summary>
    public static class StringExtensions
    {
        public static string Page(this string sql, int pageSize, int pageNumber, Sql format)
        {
            StatementCollection statements = SqlParser.Parse(sql);

            if (statements.Count > 0)
            {
                if (statements[0] is Select)
                {
                    Select select = (Select)statements[0];

                    if (format == Sql.SqlServer)
                    {
                        if (select.OrderBy.IsNull())
                        {
                            throw new InvalidOperationException("要分页的 sql 必须有 order by 从句");
                        }

                        string orderBy = sql.Substring(select.OrderBy.Begin, select.OrderBy.End - select.OrderBy.Begin + 1);

                        string over = "row_number() over({0}) as rn".FormatString(orderBy);

                        int begin = pageSize * (pageNumber - 1) + 1;

                        int end = begin + pageSize - 1;

                        if (select.End > select.OrderBy.End)
                        {
                            sql = sql.Remove(select.OrderBy.Begin - 1, select.OrderBy.End - select.OrderBy.Begin + 3);
                        }
                        else
                        {
                            sql = sql.Remove(select.OrderBy.Begin - 1, select.OrderBy.End - select.OrderBy.Begin + 2);
                        }

                        sql = sql.Insert(select.ColumnsEnd + 1, ", " + over);

                        sql = "select * from ({0}) a where rn between {1} and {2}".FormatString(sql, begin, end);
                    }
                    else if (format == Sql.MySql)
                    {

                    }
                }
            }

            return sql;
        }

        public static string And(this string sql, string conditions)
        {
            StatementCollection statements = SqlParser.Parse(sql);

            if (statements.Count > 0)
            {
                if (statements[0] is Select)
                {
                    Select select = (Select)statements[0];

                    if (select.Where.IsNull())
                    {
                        if (select.From.IsNull())
                        {
                            sql = sql.Insert(select.ColumnsEnd + 1, " where " + conditions);
                        }
                        else
                        {
                            sql = sql.Insert(select.From.End + 1, " where " + conditions);
                        }
                    }
                    else
                    {
                        sql = sql.Insert(select.Where.End + 1, " and " + conditions);
                    }
                }
            }

            return sql;
        }

        public static string Count(this string sql)
        {
            StatementCollection statements = SqlParser.Parse(sql);

            if (statements.Count > 0)
            {
                if (statements[0] is Select)
                {
                    Select select = (Select)statements[0];

                    int? begin = null;
                    int? length = null;

                    if (select.OrderBy.IsNotNull())
                    {
                        begin = select.OrderBy.Begin - 1;
                        length = select.OrderBy.End - select.OrderBy.Begin + 1;
                    }

                    if (select.Limit.IsNotNull())
                    {
                        if (begin.IsNull())
                        {
                            begin = select.Limit.Begin - 1;
                        }

                        length = select.Limit.End - begin + 1;
                    }

                    if (begin.IsNotNull())
                    {
                        if (begin + length <= select.End)
                        {
                            length = length + 1;
                        }

                        sql = sql.Remove(begin.Value, length.Value);
                    }

                    sql = sql.Remove(select.ColumnsBegin, select.ColumnsEnd - select.ColumnsBegin + 1);

                    sql = sql.Insert(select.ColumnsBegin, "count(*)");
                }
            }

            return sql;
        }
    }
}
